<template>
  <div class="lazy-image-container" :style="{ width, height }" ref="containerRef">
    <el-image
      v-if="isVisible && imageSrc"
      :src="imageSrc"
      :alt="alt"
      :style="{ width, height }"
      :fit="fit"
      :preview-src-list="previewSrcList && previewSrcList.length > 0 ? previewSrcList : undefined"
      @error="handleError"
      @load="handleLoad"
    >
      <template #placeholder>
        <div class="image-placeholder">
          <el-icon><Picture /></el-icon>
        </div>
      </template>
      <template #error>
        <div class="image-error">
          <el-icon><Picture /></el-icon>
        </div>
      </template>
    </el-image>
    <div v-else-if="!isVisible" class="image-placeholder">
      <el-icon><Picture /></el-icon>
    </div>
    <div v-else class="image-error">
      <el-icon><Picture /></el-icon>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { Picture } from '@element-plus/icons-vue'

interface Props {
  src?: string
  alt?: string
  width?: string
  height?: string
  fit?: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down'
  previewSrcList?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  src: '',
  alt: '',
  width: '50px',
  height: '50px',
  fit: 'cover',
  previewSrcList: () => []
})

const isVisible = ref(false)
const imageSrc = ref('')
const containerRef = ref<HTMLElement>()

let observer: IntersectionObserver | null = null

const handleError = () => {
  console.warn('图片加载失败:', props.src)
}

const handleLoad = () => {
  // 图片加载成功
}

const initObserver = () => {
  if (!containerRef.value) return

  // 如果没有src或者src为空，直接显示错误状态
  if (!props.src || props.src.trim() === '') {
    isVisible.value = true
    return
  }

  observer = new IntersectionObserver(
    (entries) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          isVisible.value = true
          imageSrc.value = props.src
          observer?.unobserve(entry.target)
        }
      })
    },
    {
      rootMargin: '50px' // 提前50px开始加载
    }
  )

  observer.observe(containerRef.value)
}

onMounted(() => {
  initObserver()
})

onUnmounted(() => {
  if (observer) {
    observer.disconnect()
  }
})
</script>

<style scoped>
.lazy-image-container {
  display: inline-block;
}

.image-placeholder,
.image-error {
  display: flex;
  align-items: center;
  justify-content: center;
  background-color: #f5f7fa;
  color: #909399;
  width: 100%;
  height: 100%;
  border-radius: 4px;
}

.image-placeholder .el-icon,
.image-error .el-icon {
  font-size: 20px;
}
</style>
